$.jgrid.extend({

    searchGrid: function (p) {

        var regional = $.jgrid.getRegional(this[0], 'search');
        p = $.extend(true, {
            recreateFilter: false,
            drag: true,
            sField: 'searchField',
            sValue: 'searchString',
            sOper: 'searchOper',
            sFilter: 'filters',
            loadDefaults: true, // this options activates loading of default filters from grid's postData for Multipe Search only.
            beforeShowSearch: null,
            afterShowSearch: null,
            onInitializeSearch: null,
            afterRedraw: null,
            afterChange: null,
            sortStrategy: null,
            closeAfterSearch: false,
            closeAfterReset: false,
            closeOnEscape: false,
            searchOnEnter: false,
            multipleSearch: false,
            multipleGroup: false,
            //cloneSearchRowOnAdd: true,
            top: 0,
            left: 0,
            jqModal: true,
            modal: false,
            resize: true,
            width: 450,
            height: 'auto',
            dataheight: 'auto',
            showQuery: false,
            errorcheck: true,
            sopt: null,
            stringResult: undefined,
            onClose: null,
            onSearch: null,
            onReset: null,
            toTop: true,
            overlay: 30,
            columns: [],
            tmplNames: null,
            tmplFilters: null,
            tmplLabel: ' Template: ',
            showOnLoad: false,
            layer: null,
            splitSelect: ",",
            groupOpSelect: "OR",
            operands: {
                "eq": "=",
                "ne": "<>",
                "lt": "<",
                "le": "<=",
                "gt": ">",
                "ge": ">=",
                "bw": "LIKE",
                "bn": "NOT LIKE",
                "in": "IN",
                "ni": "NOT IN",
                "ew": "LIKE",
                "en": "NOT LIKE",
                "cn": "LIKE",
                "nc": "NOT LIKE",
                "nu": "IS NULL",
                "nn": "ISNOT NULL"
            },
            buttons: []
        }, regional, p || {});
        return this.each(function () {
            var $t = this;
            if (!$t.grid) {
                return;
            }
            var fid = "fbox_" + $t.p.id,
                showFrm = true,
                mustReload = true,
                IDs = {
                    themodal: 'searchmod' + fid,
                    modalhead: 'searchhd' + fid,
                    modalcontent: 'searchcnt' + fid,
                    scrollelm: fid
                },
                defaultFilters = ($.isPlainObject($t.p_savedFilter) && !$.isEmptyObject($t.p_savedFilter)) ? $t.p_savedFilter : $t.p.postData[p.sFilter],
                fl,
                classes = $.jgrid.styleUI[($t.p.styleUI || 'jQueryUI')].filter,
                common = $.jgrid.styleUI[($t.p.styleUI || 'jQueryUI')].common;
            p.styleUI = $t.p.styleUI;
            if (typeof defaultFilters === "string") {
                defaultFilters = $.jgrid.parse(defaultFilters);
            }
            if (p.recreateFilter === true) {
                $("#" + $.jgrid.jqID(IDs.themodal)).remove();
            }

            function showFilter(_filter) {
                showFrm = $($t).triggerHandler("jqGridFilterBeforeShow", [_filter]);
                if (showFrm === undefined) {
                    showFrm = true;
                }
                if (showFrm && $.isFunction(p.beforeShowSearch)) {
                    showFrm = p.beforeShowSearch.call($t, _filter);
                }
                if (showFrm) {
                    $.jgrid.viewModal("#" + $.jgrid.jqID(IDs.themodal), {
                        gbox: "#gbox_" + $.jgrid.jqID($t.p.id),
                        jqm: p.jqModal,
                        modal: p.modal,
                        overlay: p.overlay,
                        toTop: p.toTop
                    });
                    $($t).triggerHandler("jqGridFilterAfterShow", [_filter]);
                    if ($.isFunction(p.afterShowSearch)) {
                        p.afterShowSearch.call($t, _filter);
                    }
                }
            }

            if ($("#" + $.jgrid.jqID(IDs.themodal))[0] !== undefined) {
                showFilter($("#fbox_" + $.jgrid.jqID($t.p.id)));
            } else {
                var fil = $("<div><div id='" + fid + "' class='searchFilter' style='overflow:auto'></div></div>").insertBefore("#gview_" + $.jgrid.jqID($t.p.id)),
                    align = "left", butleft = "";
                if ($t.p.direction === "rtl") {
                    align = "right";
                    butleft = " style='text-align:left'";
                    fil.attr("dir", "rtl");
                }
                var columns = $.extend([], $t.p.colModel),
                    bS = "<a id='" + fid + "_search' class='fm-button " + common.button + " fm-button-icon-right ui-search'><span class='" + common.icon_base + " " + classes.icon_search + "'></span>" + p.Find + "</a>",
                    bC = "<a id='" + fid + "_reset' class='fm-button " + common.button + " fm-button-icon-left ui-reset'><span class='" + common.icon_base + " " + classes.icon_reset + "'></span>" + p.Reset + "</a>",
                    bQ = "", tmpl = "", colnm, found = false, bt, cmi = -1, ms = false, ssfield = [];
                if (p.showQuery) {
                    bQ = "<a id='" + fid + "_query' class='fm-button " + common.button + " fm-button-icon-left'><span class='" + common.icon_base + " " + classes.icon_query + "'></span>Query</a>";
                }
                var user_buttons = $.jgrid.buildButtons(p.buttons, bQ + bS, common);
                if (!p.columns.length) {
                    $.each(columns, function (i, n) {
                        if (!n.label) {
                            n.label = $t.p.colNames[i];
                        }
                        // find first searchable column and set it if no default filter
                        if (!found) {
                            var searchable = (n.search === undefined) ? true : n.search,
                                hidden = (n.hidden === true),
                                ignoreHiding = (n.searchoptions && n.searchoptions.searchhidden === true);
                            if ((ignoreHiding && searchable) || (searchable && !hidden)) {
                                found = true;
                                colnm = n.index || n.name;
                                cmi = i;
                            }
                        }
                        if (n.stype === "select" && n.searchoptions && n.searchoptions.multiple) {
                            ms = true;
                            ssfield.push(n.index || n.name);
                        }
                    });
                } else {
                    columns = p.columns;
                    cmi = 0;
                    colnm = columns[0].index || columns[0].name;
                }
                // old behaviour
                if ((!defaultFilters && colnm) || p.multipleSearch === false) {
                    var cmop = "eq";
                    if (cmi >= 0 && columns[cmi].searchoptions && columns[cmi].searchoptions.sopt) {
                        cmop = columns[cmi].searchoptions.sopt[0];
                    } else if (p.sopt && p.sopt.length) {
                        cmop = p.sopt[0];
                    }
                    defaultFilters = {groupOp: "AND", rules: [{field: colnm, op: cmop, data: ""}]};
                }
                found = false;
                if (p.tmplNames && p.tmplNames.length) {
                    found = true;
                    tmpl = "<tr><td class='ui-search-label'>" + p.tmplLabel + "</td>";
                    tmpl += "<td><select class='ui-template " + classes.srSelect + "'>";
                    tmpl += "<option value='default'>Default</option>";
                    $.each(p.tmplNames, function (i, n) {
                        tmpl += "<option value='" + i + "'>" + n + "</option>";
                    });
                    tmpl += "</select></td></tr>";
                }
                var tmplSwitch = "<tr><td class='ui-search-label'>记录搜索模板:</td><td><input id='" + fid + "_tmplSwitch' type='checkbox' ></td><td><input style='visibility:hidden;' placeholder='请输入模板名称' class='input-elm form-control' id='" + fid + "_tmplName'  type='text'></td></tr>" + "<tr><td colspan='2'><hr class='" + common.content + "' style='margin:1px'/></td></tr>";

                //
                tmpl += tmplSwitch;

                bt = "<table class='EditTable' style='border:0px none;margin-top:5px' id='" + fid + "_2'>" +
                    "<tbody><tr><td colspan='2'><hr class='" + common.content + "' style='margin:1px'/></td></tr>" + tmpl +
                    "<tr><td class='EditButton' style='text-align:" + align + "'>" + bC + "</td><td class='EditButton' " + butleft + ">" + user_buttons + "</td></tr></tbody></table>";


                fid = $.jgrid.jqID(fid);
                $("#" + fid).jqFilter({
                    columns: columns,
                    sortStrategy: p.sortStrategy,
                    filter: p.loadDefaults ? defaultFilters : null,
                    showQuery: p.showQuery,
                    errorcheck: p.errorcheck,
                    sopt: p.sopt,
                    groupButton: p.multipleGroup,
                    ruleButtons: p.multipleSearch,
                    uniqueSearchFields: p.uniqueSearchFields,
                    afterRedraw: p.afterRedraw,
                    ops: p.odata,
                    operands: p.operands,
                    ajaxSelectOptions: $t.p.ajaxSelectOptions,
                    groupOps: p.groupOps,
                    addsubgrup: p.addsubgrup,
                    addrule: p.addrule,
                    delgroup: p.delgroup,
                    delrule: p.delrule,
                    autoencode: $t.p.autoencode,
                    onChange: function () {
                        if (this.p.showQuery) {
                            $('.query', this).html(this.toUserFriendlyString());
                        }
                        if ($.isFunction(p.afterChange)) {
                            p.afterChange.call($t, $("#" + fid), p);
                        }
                    },
                    direction: $t.p.direction,
                    id: $t.p.id
                });

                fil.append(bt);

                $("#" + fid + "_2").find("[data-index]").each(function () {
                    var index = parseInt($(this).attr('data-index'), 10);
                    if (index >= 0) {
                        $(this).on('click', function (e) {
                            p.buttons[index].click.call($t, $("#" + fid), p, e);
                        });
                    }
                });
                if (found && p.tmplFilters && p.tmplFilters.length) {
                    $(".ui-template", fil).on('change', function () {
                        var curtempl = $(this).val();
                        if (curtempl === "default") {
                            $("#" + fid).jqFilter('addFilter', defaultFilters);
                        } else {
                            $("#" + fid).jqFilter('addFilter', p.tmplFilters[parseInt(curtempl, 10)]);
                        }
                        return false;
                    });
                }
                if (p.multipleGroup === true) {
                    p.multipleSearch = true;
                }
                $($t).triggerHandler("jqGridFilterInitialize", [$("#" + fid)]);
                if ($.isFunction(p.onInitializeSearch)) {
                    p.onInitializeSearch.call($t, $("#" + fid));
                }
                p.gbox = "#gbox_" + fid;
                if (p.layer) {
                    $.jgrid.createModal(IDs, fil, p, "#gview_" + $.jgrid.jqID($t.p.id), $("#gbox_" + $.jgrid.jqID($t.p.id))[0], (typeof p.layer === "string" ? "#" + $.jgrid.jqID(p.layer) : p.layer), (typeof p.layer === "string" ? {position: "relative"} : {}));
                } else {
                    $.jgrid.createModal(IDs, fil, p, "#gview_" + $.jgrid.jqID($t.p.id), $("#gbox_" + $.jgrid.jqID($t.p.id))[0]);
                }
                if (p.searchOnEnter || p.closeOnEscape) {
                    $("#" + $.jgrid.jqID(IDs.themodal)).keydown(function (e) {
                        var $target = $(e.target);
                        if (p.searchOnEnter && e.which === 13 && // 13 === $.ui.keyCode.ENTER
                            !$target.hasClass('add-group') && !$target.hasClass('add-rule') &&
                            !$target.hasClass('delete-group') && !$target.hasClass('delete-rule') &&
                            (!$target.hasClass("fm-button") || !$target.is("[id$=_query]"))) {
                            $("#" + fid + "_search").click();
                            return false;
                        }
                        if (p.closeOnEscape && e.which === 27) { // 27 === $.ui.keyCode.ESCAPE
                            $("#" + $.jgrid.jqID(IDs.modalhead)).find(".ui-jqdialog-titlebar-close").click();
                            return false;
                        }
                    });
                }
                if (bQ) {
                    $("#" + fid + "_query").on('click', function () {
                        $(".queryresult", fil).toggle();
                        return false;
                    });
                }
                if (p.stringResult === undefined) {
                    // to provide backward compatibility, inferring stringResult value from multipleSearch
                    p.stringResult = p.multipleSearch;
                }


                $("#" + fid + "_tmplSwitch").change(function () {

                    if ($("#" + fid + "_tmplSwitch").is(':checked')) {
                        $("#" + fid + "_tmplName").css("visibility", "visible");
                    } else {
                        $("#" + fid + "_tmplName").css("visibility", "hidden");

                    }


                });


                $("#" + fid + "_search").on('click', function () {

                    var sdata = {}, res, filters;
                    fl = $("#" + fid);
                    fl.find(".input-elm:focus").change();
                    if (ms && p.multipleSearch) {
                        $t.p_savedFilter = {};
                        filters = $.jgrid.filterRefactor({
                            ruleGroup: $.extend(true, {}, fl.jqFilter('filterData')),
                            ssfield: ssfield,
                            splitSelect: p.splitSelect,
                            groupOpSelect: p.groupOpSelect
                        });
                        $t.p_savedFilter = $.extend(true, {}, fl.jqFilter('filterData'));
                    } else {
                        filters = fl.jqFilter('filterData');
                    }
                    if (p.errorcheck) {
                        fl[0].hideError();
                        if (!p.showQuery) {
                            fl.jqFilter('toSQLString');
                        }
                        if (fl[0].p.error) {
                            fl[0].showError();
                            return false;
                        }
                    }


                    if ($("#" + fid + "_tmplSwitch").is(':checked')) {


                        var _tmplName = $("#" + fid + "_tmplName").val();
                        if ($("#" + fid + "_tmplName").val() == "") {
                            return
                        }
                        //拿到搜索字符串
                        var tmplName = $.cookie("tmplName");

                        if (tmplName) {
                            var arr = tmplName.split(",");
                            arr.push(_tmplName);
                            $.cookie("tmplName", arr.join(","))
                        } else {
                            $.cookie("tmplName", _tmplName);
                        }
                        $.cookie("searchTmpl_" + _tmplName, JSON.stringify(filters));

                    }


                    if (p.stringResult) {
                        try {
                            res = JSON.stringify(filters);
                        } catch (e2) {
                        }
                        if (typeof res === "string") {
                            sdata[p.sFilter] = res;
                            $.each([p.sField, p.sValue, p.sOper], function () {
                                sdata[this] = "";
                            });
                        }
                    } else {
                        if (p.multipleSearch) {
                            sdata[p.sFilter] = filters;
                            $.each([p.sField, p.sValue, p.sOper], function () {
                                sdata[this] = "";
                            });
                        } else {
                            sdata[p.sField] = filters.rules[0].field;
                            sdata[p.sValue] = filters.rules[0].data;
                            sdata[p.sOper] = filters.rules[0].op;
                            sdata[p.sFilter] = "";
                        }
                    }
                    $t.p.search = true;
                    $.extend($t.p.postData, sdata);
                    mustReload = $($t).triggerHandler("jqGridFilterSearch");
                    if (mustReload === undefined) {
                        mustReload = true;
                    }
                    if (mustReload && $.isFunction(p.onSearch)) {
                        mustReload = p.onSearch.call($t, $t.p.filters);
                    }
                    if (mustReload !== false) {
                        $($t).trigger("reloadGrid", [{page: 1}]);
                    }
                    if (p.closeAfterSearch) {
                        $.jgrid.hideModal("#" + $.jgrid.jqID(IDs.themodal), {
                            gb: "#gbox_" + $.jgrid.jqID($t.p.id),
                            jqm: p.jqModal,
                            onClose: p.onClose
                        });
                    }
                    return false;
                });
                $("#" + fid + "_reset").on('click', function () {
                    var sdata = {},
                        fl = $("#" + fid);
                    $t.p.search = false;
                    $t.p.resetsearch = true;
                    if (p.multipleSearch === false) {
                        sdata[p.sField] = sdata[p.sValue] = sdata[p.sOper] = "";
                    } else {
                        sdata[p.sFilter] = "";
                    }
                    fl[0].resetFilter();
                    if (found) {
                        $(".ui-template", fil).val("default");
                    }
                    $.extend($t.p.postData, sdata);
                    mustReload = $($t).triggerHandler("jqGridFilterReset");
                    if (mustReload === undefined) {
                        mustReload = true;
                    }
                    if (mustReload && $.isFunction(p.onReset)) {
                        mustReload = p.onReset.call($t);
                    }
                    if (mustReload !== false) {
                        $($t).trigger("reloadGrid", [{page: 1}]);
                    }
                    if (p.closeAfterReset) {
                        $.jgrid.hideModal("#" + $.jgrid.jqID(IDs.themodal), {
                            gb: "#gbox_" + $.jgrid.jqID($t.p.id),
                            jqm: p.jqModal,
                            onClose: p.onClose
                        });
                    }
                    return false;
                });
                showFilter($("#" + fid));
                $(".fm-button:not(." + common.disabled + ")", fil).hover(
                    function () {
                        $(this).addClass(common.hover);
                    },
                    function () {
                        $(this).removeClass(common.hover);
                    }
                );
            }
        });
    },

});